package com.mobilesales.android.activities.orders;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

import com.mobilesales.android.R;
import com.mobilesales.android.activities.ListModelActivity;
import com.mobilesales.android.activities.clients.Clients;
import com.mobilesales.android.activities.products.Products;
import com.mobilesales.android.adapters.OrderItemAdapter;
import com.mobilesales.android.adapters.OrderStatusAdapter;
import com.mobilesales.android.database.ClientManager;
import com.mobilesales.android.database.OrderManager;
import com.mobilesales.android.database.ProductManager;
import com.mobilesales.android.model.clients.Client;
import com.mobilesales.android.model.orders.Order;
import com.mobilesales.android.model.orders.OrderItem;
import com.mobilesales.android.model.orders.OrderStatus;
import com.mobilesales.android.model.products.Product;
import com.mobilesales.android.services.OrderServiceClient;
import com.mobilesales.android.util.Constants;
import com.mobilesales.android.util.DateUtil;
import com.mobilesales.android.util.LogFlags;
import com.mobilesales.android.util.MessageBox;
import com.mobilesales.android.util.Settings;

public class StoreOrder extends ListModelActivity<OrderItem> {

	private TextView clientField;
	private Spinner orderStatusSpinner;

	private List<OrderStatus> statuses;
	private OrderStatusAdapter orderStatusAdapter;

	private int orderId = 0;
	private Order order;

	private Client selectedClient;
	private OrderItemAdapter orderItemsAdapter;

	private final Handler handler = new Handler();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.order_store);

		clientField = (TextView) this.findViewById(R.id.clientTxt);
		orderStatusSpinner = (Spinner) this
				.findViewById(R.id.orderStatusSpinner);

		Bundle bundle = this.getIntent().getExtras();
		if (bundle != null && bundle.containsKey(Constants.OrderId)) {
			orderId = bundle.getInt(Constants.OrderId);
		}
		this.registerForContextMenu(getListView());
		loadItems();
		
	}

	private void loadItems() {
		statuses = this.getOrderStatuses();
		if (statuses != null) {
			orderStatusAdapter = new OrderStatusAdapter(this,
					R.layout.select_list_item, statuses);
			this.orderStatusSpinner.setAdapter(this.orderStatusAdapter);
			this.fixSpinner(this.orderStatusSpinner);
			if (this.orderId != 0) {
				this.order = this.getOrder(orderId);
				if (this.order != null) {
					this.selectedClient = this.getClient(order.ClientId);
					if (this.selectedClient != null) {
						String clientStr = String.format("%s\n%s\n%s, %s",
								selectedClient.Name, selectedClient.Street,
								selectedClient.Zipcode, selectedClient.City);
						this.clientField.setText(clientStr);
						this.orderStatusSpinner.setSelection(orderStatusAdapter
								.getPosition(order.Status.Id));
						this.orderItemsAdapter = new OrderItemAdapter(this,
								R.layout.order_item_list_item, order.Items);
						this.orderItemsAdapter.setClient(this.selectedClient);
						this.setListAdapter(orderItemsAdapter);
					} else {
						MessageBox.show(this, getString(R.string.ErrorClient));
						finish();
					}
				} else {
					MessageBox.show(this, getString(R.string.ErrorOrder));
					finish();
				}
			} else {
				this.orderItemsAdapter = new OrderItemAdapter(this,
						R.layout.order_item_list_item,
						new ArrayList<OrderItem>());
			}
		} else {
			MessageBox.show(this, getString(R.string.ErrorOrderStatusList));
			finish();
		}
	}

	public void refresh() {
		handler.post(new Runnable() {
			public void run() {
				loadItems();
			}
		});
	}
	
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		
		AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
		Log.i("contextMenu","position:"+info.position);
		menu.add(Menu.NONE, 0, 0, getString(R.string.Delete));
	}	
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
		Log.i("contextMenu","position:"+info.position+" action:"+item.getItemId());
		switch(item.getItemId()) {
			case 0: //delete
				OrderItem oItem = orderItemsAdapter.getItem(info.position);
				orderItemsAdapter.remove(oItem);
				orderItemsAdapter.notifyDataSetChanged();
				break;
		}
		return true;
	}	
	

	public void selectClient(View v) {
		Intent intent = new Intent(this, Clients.class);
		intent.putExtra(Constants.RequestCode,
				Constants.RequestCodes.ChooseClient);
		this.startActivityForResult(intent, Constants.RequestCodes.ChooseClient);
	}

	public void selectProduct(View v) {
		Intent intent = new Intent(this, Products.class);
		intent.putExtra(Constants.RequestCode,
				Constants.RequestCodes.ChooseProduct);
		this.startActivityForResult(intent,
				Constants.RequestCodes.ChooseProduct);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		Bundle bundle = (data != null) ? data.getExtras() : null;
		switch (requestCode) {
		case Constants.RequestCodes.ChooseClient:
			if (bundle != null && bundle.containsKey(Constants.ClientId)) {
				this.selectedClient = this.getClient(bundle
						.getInt(Constants.ClientId));
				if (this.selectedClient != null) {
					String clientStr = String.format("%s\n%s\n%s, %s",
							selectedClient.Name, selectedClient.Street,
							selectedClient.Zipcode, selectedClient.City);
					this.clientField.setText(clientStr);
				} else {
					MessageBox.show(this, getString(R.string.ErrorClient));
				}
			}
			break;
		case Constants.RequestCodes.ChooseProduct:

			if (bundle != null && bundle.containsKey(Constants.ProductId)) {
				Product product = this.getProduct(bundle
						.getInt(Constants.ProductId));
				if (product != null)
					this.addItem(product);
				else
					MessageBox.show(this, getString(R.string.ErrorProduct));
			}
			break;
		}
	}

	private void addItem(Product product) {
		final OrderItem item = new OrderItem();
		item.Product = product;

		AlertDialog.Builder alert = new AlertDialog.Builder(this);
		alert.setTitle(this.getString(R.string.Quantity));
		final EditText input = new EditText(this);
		alert.setView(input);
		alert.setPositiveButton(this.getString(R.string.Ok),
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						String value = input.getText().toString();
						try {
							double quantity = Double.parseDouble(value);
							item.Quantity = quantity;
							orderItemsAdapter.add(item);
							setListAdapter(orderItemsAdapter);
						} catch (Exception ex) {
							input.setError(input.getContext().getString(
									R.string.ErrorInvalidValue));
						}
					}
				});

		alert.setNegativeButton(getString(R.string.Cancel),
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int whichButton) {
						dialog.dismiss();
					}
				});

		alert.show();
	}

	public void store(View v) {
		if (validate()) {
			this.order = new Order();
			order.Date = DateUtil.toDateString(new Date());
			order.Status = (OrderStatus) this.orderStatusSpinner
					.getSelectedItem();
			order.ClientId = selectedClient.Id;
			order.Items = new ArrayList<OrderItem>();
			for (int i = 0; i < orderItemsAdapter.getCount(); i++) {
				order.Items.add(orderItemsAdapter.getItem(i));
			}
			if (save(order)) {
				MessageBox.show(this,
						getString(R.string.OrderSavedSuccessfully));
				finish();
			} else
				MessageBox.show(this, getString(R.string.ErrorSave));
		}
	}

	private boolean save(Order order) {
		try {
			OrderServiceClient service = new OrderServiceClient(Settings.OrderService());
			service.StoreOrder(order);
			return true;
		} catch (Exception e) {
			Log.e(LogFlags.RestService, e.getMessage(), e);
		}
		return false;
	}

	private List<OrderStatus> getOrderStatuses() {
		OrderManager manager = new OrderManager(this);
		List<OrderStatus> result = manager.GetOrderStatusList();
		manager.Close();
		return result;
	}

	private Order getOrder(int orderId) {
		OrderManager manager = new OrderManager(this);
		Order result = manager.GetOrder(orderId);
		manager.Close();
		return result;
	}

	private Client getClient(int clientId) {
		ClientManager manager = new ClientManager(this);
		Client result = manager.GetClient(clientId);
		manager.Close();
		return result;
	}

	private Product getProduct(int productId) {
		ProductManager manager = new ProductManager(this);
		Product result = manager.GetProduct(productId);
		manager.Close();
		return result;
	}

	private boolean validate() {
		if (this.selectedClient == null) {
			MessageBox.show(this, getString(R.string.ErrorClientNotSelected));
			return false;
		}

		if (this.orderItemsAdapter.getCount() == 0) {
			MessageBox.show(this, getString(R.string.ErrorOrderListEmpty));
			return false;
		}
		return true;
	}

	private void fixSpinner(Spinner spinner) {
		DisplayMetrics d = new DisplayMetrics();
		getWindow().getWindowManager().getDefaultDisplay().getMetrics(d);
		int wdt = d.widthPixels;
		spinner.getLayoutParams().width = wdt - 10;
	}
}
